package org.example.domain.strategy.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.example.domain.strategy.model.entity.RaffleAwardEntity;
import org.example.domain.strategy.model.entity.RaffleFactorEntity;
import org.example.domain.strategy.model.entity.RuleActionEntity;
import org.example.domain.strategy.model.entity.StrategyEntity;
import org.example.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import org.example.domain.strategy.model.vo.StrategyAwardRuleModelVO;
import org.example.domain.strategy.repository.IStrategyRepository;
import org.example.domain.strategy.service.IRaffleStrategy;
import org.example.domain.strategy.service.armory.IStrategyDispatch;
import org.example.domain.strategy.service.rule.chain.ILogicChain;
import org.example.domain.strategy.service.rule.chain.factory.DefaultChainFactory;

import org.example.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import org.example.types.enums.ResponseCode;
import org.example.types.exception.AppException;

/**
 * 抽奖策略抽象类
 * <p>
 * 规定整体抽奖流程和规则过滤
 */


@Slf4j
public abstract class AbstractRaffleStrategy implements IRaffleStrategy,IRaffleStock {


    //粗略仓储服务  提供抽奖需要的基本数据
    protected IStrategyRepository repository;

    //策略调度服务  只负责抽奖 不关心抽奖初始化
    protected IStrategyDispatch strategyDispatch;

    protected final DefaultChainFactory defaultChainFactory;

    protected final DefaultTreeFactory defaultTreeFactory;

    public AbstractRaffleStrategy(IStrategyRepository repository, IStrategyDispatch strategyDispatch, DefaultChainFactory defaultChainFactory,DefaultTreeFactory defaultTreeFactory) {

        this.repository = repository;
        this.strategyDispatch = strategyDispatch;
        this.defaultChainFactory = defaultChainFactory;
        this.defaultTreeFactory = defaultTreeFactory;
    }


    @Override
    public RaffleAwardEntity performRaffle(RaffleFactorEntity raffleFactorEntity) {

        // 1.  参数校验
        String userId = raffleFactorEntity.getUserId();
        Long strategyId = raffleFactorEntity.getStrategyId();
        if (strategyId == null || StringUtils.isBlank(userId)) {
            throw new AppException(ResponseCode.ILLEGAL_PARAMETER.getCode(), ResponseCode.ILLEGAL_PARAMETER.getInfo());
        }

        //2.抽奖责任链规律规则---初步抽奖结果（如果进入黑名单、权重，结果就直接返回抽奖结果）
        DefaultChainFactory.strategyAwardVO strategyAwardVO = raffleChain(userId, strategyId);
        log.info("抽奖责任链");
        if (!DefaultChainFactory.logicModel.RULE_DEFAULT.getInfo().equals(strategyAwardVO.getLogicModel()))
            return RaffleAwardEntity.builder()
                    .awardId(strategyAwardVO.getAwardId())
                    .build();

        //3.抽奖规则树过滤规则
        DefaultTreeFactory.StrategyAwardData strategyAwardData = raffleTree(userId, strategyId,strategyAwardVO.getAwardId());
        log.info("抽奖规则树");


        //4.返回抽奖结果
        return RaffleAwardEntity.builder()
                .awardId(strategyAwardData.getAwardId())
                .awardConfig(strategyAwardData.getAwardRuleValue())
                .build();
    }

    public abstract DefaultChainFactory.strategyAwardVO raffleChain(String userId, Long StrategyId);

    public abstract DefaultTreeFactory.StrategyAwardData raffleTree(String userId, Long StrategyId,Integer awardId);


}